﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;

namespace Flickr.Owin.Security.FlickrOAuth
{
    internal static class UtilityMethods
    {
        private static readonly DateTime UnixStartDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

        public static string DateToUnixTimestamp(DateTime date)
        {
            return (date - UnixStartDate).TotalSeconds.ToString("0", (IFormatProvider)NumberFormatInfo.InvariantInfo);
        }

        public static string AuthLevelToString(AuthLevel level)
        {
            switch (level)
            {
                case AuthLevel.None:
                    return "none";
                case AuthLevel.Read:
                    return "read";
                case AuthLevel.Write:
                    return "write";
                case AuthLevel.Delete:
                    return "delete";
                default:
                    return string.Empty;
            }
        }

        public static Dictionary<string, string> StringToDictionary(string response)
        {
            var dictionary = new Dictionary<string, string>();
            if (string.IsNullOrEmpty(response))
                return dictionary;
            string str1 = response;
            var chArray = new char[1]
             {
               '&'
             };
            foreach (string str2 in str1.Split(chArray))
            {
                var separator = new char[1]
                {
                '='
                };
                int count = 2;
                int num = 1;
                string[] strArray = str2.Split(separator, count, (StringSplitOptions)num);
                dictionary.Add(strArray[0], strArray.Length == 1 ? "" : Uri.UnescapeDataString(strArray[1]));
            }
            return dictionary;
        }

        public static string OAuthCalculateSignature(string method, string url, Dictionary<string, string> parameters, string tokenSecret, string apiSecret)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(apiSecret + "&" + tokenSecret);
            SortedList<string, string> sortedList = new SortedList<string, string>();
            foreach (KeyValuePair<string, string> keyValuePair in parameters)
                sortedList.Add(keyValuePair.Key, keyValuePair.Value);
            StringBuilder stringBuilder = new StringBuilder();
            foreach (KeyValuePair<string, string> keyValuePair in sortedList)
            {
                stringBuilder.Append(keyValuePair.Key);
                stringBuilder.Append("=");
                stringBuilder.Append(EscapeOAuthString(keyValuePair.Value));
                stringBuilder.Append("&");
            }
            stringBuilder.Remove(stringBuilder.Length - 1, 1);
            string s = method + "&" + EscapeOAuthString(url) + "&" + EscapeOAuthString(((object)stringBuilder).ToString());
            return Convert.ToBase64String(new HMACSHA1(bytes).ComputeHash(Encoding.UTF8.GetBytes(s)));
        }

        public static string EscapeOAuthString(string text)
        {
            return Regex.Replace(Uri.EscapeDataString(text).Replace("+", "%20"), "(%[0-9a-f][0-9a-f])", (MatchEvaluator)(c => c.Value.ToUpper())).Replace("(", "%28").Replace(")", "%29").Replace("$", "%24").Replace("!", "%21").Replace("*", "%2A").Replace("'", "%27").Replace("%7E", "~");
        }
    }
}